package com.acg.auth.service.impl;

import com.acg.auth.mapper.SysRoleMenuMapper;
import com.acg.auth.pojo.SysMenu;
import com.acg.auth.mapper.SysMenuMapper;
import com.acg.auth.pojo.SysRoleMenu;
import com.acg.auth.service.SysMenuService;
import com.acg.auth.vo.AssignMenuVo;
import com.acg.auth.vo.MetaVo;
import com.acg.auth.vo.RouterVo;
import com.acg.exception.ACGException;
import com.acg.util.MenuHelper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单表 服务实现类
 * </p>
 *
 * @author acg
 * @since 2025-08-08
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {
    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;

    @Resource
    private SysMenuMapper menuMapper;


    /**
     * 返回树状信息
     * @return
     */

    @Override
    public List<SysMenu> getAllMenu() {
        // 1、 获取所有菜单信息
        List<SysMenu> menuList = this.list();

        // 2、 构建树形结构
        List<SysMenu> sysMenus = MenuHelper.buildTree(menuList);

        return sysMenus;
    }

    /**
     * 菜单删除
     * @param id        菜单主键
     * @return
     */
    @Override
    public boolean deleteById(Long id) throws ACGException {
        // 只有当菜单主键 不是其他菜单的parent_id 的时候才能删除
        LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
        // 如果当前主键和 其他数据的getParentId 一致就不能删除
        wrapper.eq(SysMenu::getParentId,id);

        // 返回符合条件的个数
        int count = this.count(wrapper);

        if (count > 0) {
            throw new ACGException("该菜单下有子菜单，无法删除", 30006);
        }
        // 进行删除
        return this.removeById(id);
    }

    /**
     * 查找菜单
     * @param roleId
     * @return
     */
    @Override
    public List<SysMenu> findSysMenuByRoleId(Long roleId) {
        //1、 全部权限列表
        List<SysMenu> allSysMenuList = this.list(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getStatus, 1));

        //根据角色id获取角色权限
        List<SysRoleMenu> sysRoleMenuList = sysRoleMenuMapper.selectList(new LambdaQueryWrapper<SysRoleMenu>().eq(SysRoleMenu::getRoleId, roleId));
        //转换给角色id与角色权限对应Map对象
        // 提取菜单(权限) id
        List<Long> menuIdList = sysRoleMenuList.stream().map(e -> e.getMenuId()).collect(Collectors.toList());

        //  遍历 全部权限列表
        allSysMenuList.forEach(permission -> {
            if (menuIdList.contains(permission.getId())) {
                // 对于当前 roleId 来说 是否对应已选择的权限
                permission.setSelect(true);
            } else {
                permission.setSelect(false);
            }
        });

        // 构建树状返回
        List<SysMenu> sysMenuList = MenuHelper.buildTree(allSysMenuList);
        return sysMenuList;
    }

    /**
     * 给角色分配权限    （先删除原有的权限 再增加新的）
     * @param assignMenuVo
     */
    @Transactional
    @Override
    public void doAssign(AssignMenuVo assignMenuVo) {

        // 1 删除角色id 菜单关系
        LambdaQueryWrapper<SysRoleMenu> eq = new LambdaQueryWrapper<SysRoleMenu>()
                .eq(SysRoleMenu::getRoleId, assignMenuVo.getRoleId());
        // 2、 删除
        sysRoleMenuMapper.delete(eq);

        // 3 遍历 角色菜单
        for (Long menuId : assignMenuVo.getMenuIdList()) {
            // 创建对象
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setRoleId(assignMenuVo.getRoleId());
            sysRoleMenu.setMenuId(menuId);
            // 4 插入数据
            sysRoleMenuMapper.insert(sysRoleMenu);
        }
    }

    /**
     * 根据用户获取菜单权限
     * @param userId
     * @return
     */
    @Override
    public List<RouterVo> findUserMenuList(Long userId) {

        System.err.println("1111");
        //超级管理员admin账号id为：1
        List<SysMenu> sysMenuList = null;
        // 当用户为admin 主键为1 时 拥有所有权限
        if (userId.longValue() == 1) {
            sysMenuList = this.list(new LambdaQueryWrapper<SysMenu>()
                    .eq(SysMenu::getStatus, 1)
                    .orderByAsc(SysMenu::getSortValue));
        } else {
            //  查找对应的数据
            sysMenuList = menuMapper.findListByUserId(userId);
        }
        //构建树形数据
        List<SysMenu> sysMenuTreeList = MenuHelper.buildTree(sysMenuList);

        // 构建菜单
        List<RouterVo> routerVoList = this.buildMenus(sysMenuTreeList);
        return routerVoList;

    }

    /**
     *  构建树状的 路由
     * @param sysMenuTreeList
     * @return
     */
    private List<RouterVo> buildMenus(List<SysMenu> sysMenuTreeList) {
        // 创建 RouterVo list
        List<RouterVo> routers = new LinkedList<RouterVo>();
        for (SysMenu menu : sysMenuTreeList) {

            /**
             * 构建router需要的数据
             */
            RouterVo router = new RouterVo();
            router.setHidden(false);
            router.setAlwaysShow(false);
            router.setPath(getRouterPath(menu));
            router.setComponent(menu.getComponent());
            router.setMeta(new MetaVo(menu.getName(), menu.getIcon()));
            List<SysMenu> children = menu.getChildren();
            //如果当前是菜单，需将按钮对应的路由加载出来，如：“角色授权”按钮对应的路由在“系统管理”下面
            if(menu.getType().intValue() == 1) {

                // 查看children 获取children 信息
                List<SysMenu> hiddenMenuList = children.stream()
                        .filter(item -> !StringUtils.isEmpty(item.getComponent()))
                        .collect(Collectors.toList());

                /**
                 *
                 */
                for (SysMenu hiddenMenu : hiddenMenuList) {
                    // RouterVo 构建RouterVo
                    RouterVo hiddenRouter = new RouterVo();
                    hiddenRouter.setHidden(true);
                    hiddenRouter.setAlwaysShow(false);
                    hiddenRouter.setPath(getRouterPath(hiddenMenu));
                    hiddenRouter.setComponent(hiddenMenu.getComponent());
                    hiddenRouter.setMeta(new MetaVo(hiddenMenu.getName(), hiddenMenu.getIcon()));
                    routers.add(hiddenRouter);
                }
            } else {

                if (!CollectionUtils.isEmpty(children)) {
                    if(children.size() > 0) {
                        router.setAlwaysShow(true);
                    }
                    router.setChildren(buildMenus(children));
                }
            }
            routers.add(router);
        }
        return routers;
    }
//
//    /**
//     * 获取路由 路径
//     * @param menu
//     * @return
//     */
    private String getRouterPath(SysMenu menu) {
        // 获取原来的 Path
        String routerPath = "/" + menu.getPath();
        if(menu.getParentId().intValue() != 0) {
            routerPath = menu.getPath();
        }
        return routerPath;
    }

    /**
     * 根据用户主键获取 按钮权限
     * @param  userId
     * @return
     */
    @Override
    public List<String> findUserPermsList(Long userId) {
        //超级管理员admin账号id为：1
        List<SysMenu> sysMenuList = null;
        if (userId.longValue() == 1) {
            sysMenuList = this.list(new LambdaQueryWrapper<SysMenu>().eq(SysMenu::getStatus, 1));
        } else {
            sysMenuList = menuMapper.findListByUserId(userId);
        }
        // filter(item -> item.getType() == 2) 过滤按钮
        List<String> permsList = sysMenuList.stream()
                .filter(item -> item.getType() == 2)
                .map(item -> item.getPerms()).collect(Collectors.toList());
        return permsList;

    }

}
